﻿using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;

namespace HalconDotNet
{
	/// <summary>
	///   This control encapsulates a native HALCON window
	///   for use within a WPF framework.
	/// </summary>
	// Token: 0x02000002 RID: 2
	[ToolboxBitmap(typeof(HWindowControlWPF), "HWindowControlWPF.icon.bmp")]
	public class HWindowControlWPF : UserControl, IDisposable
	{
		// Token: 0x06000001 RID: 1 RVA: 0x00002050 File Offset: 0x00000250
		public HWindowControlWPF()
		{
			this.windowCanvas = new Canvas();
			this.windowCanvas.Margin = new Thickness(0.0, 0.0, 0.0, 0.0);
			this.windowCanvas.Background = System.Windows.Media.Brushes.Red;
			this.windowCanvas.Height = double.NaN;
			this.windowCanvas.Width = double.NaN;
			base.Content = this.windowCanvas;
			this.windowCanvas.Loaded += this.windowCanvas_Loaded;
			this.windowCanvas.SizeChanged += this.windowCanvas_SizeChanged;
			base.Width = double.NaN;
			base.Height = double.NaN;
			base.Background = System.Windows.Media.Brushes.LightGreen;
		}

		// Token: 0x06000002 RID: 2 RVA: 0x0000216C File Offset: 0x0000036C
		private void ApplyScalingFactor(Visual visual)
		{
			PresentationSource presentationSource = PresentationSource.FromVisual(visual);
			if (presentationSource != null)
			{
				Matrix transformToDevice = presentationSource.CompositionTarget.TransformToDevice;
				double m = transformToDevice.M11;
				double m2 = transformToDevice.M22;
				if (m != 0.0 && m != 0.0)
				{
					double scaleX = 1.0 / m;
					double scaleY = 1.0 / m2;
					this.windowCanvas.LayoutTransform = new ScaleTransform(scaleX, scaleY);
					this.windowCanvas.UpdateLayout();
				}
			}
		}

		// Token: 0x06000003 RID: 3 RVA: 0x000021F0 File Offset: 0x000003F0
		private void windowCanvas_Loaded(object sender, RoutedEventArgs e)
		{
			if (this.windowWPF != null)
			{
				return;
			}
			this.windowCanvas.Background = System.Windows.Media.Brushes.Black;
			if (base.IsVisible)
			{
				this.ApplyScalingFactor(this);
			}
			else
			{
				this.windowCanvas.IsVisibleChanged += this.windowCanvas_IsVisibleChanged;
			}
			if (!DesignerProperties.GetIsInDesignMode(this))
			{
				try
				{
					HObject hobject;
					HOperatorSet.GenEmptyObj(out hobject);
					hobject.Dispose();
					this.windowWPF = new HWindowWPF(this);
					this.windowWPF.HWButtonEvent += this.windowWPF_ButtonEvent;
					this.windowWPF.HWMouseEvent += this.windowWPF_MouseEvent;
					this.windowWPF.HWInitEvent += this.windowWPF_InitEvent;
					this.windowCanvas.Children.Add(this.windowWPF);
				}
				catch (DllNotFoundException)
				{
				}
			}
		}

		// Token: 0x17000001 RID: 1
		// (get) Token: 0x06000004 RID: 4 RVA: 0x000022D0 File Offset: 0x000004D0
		internal Canvas Container
		{
			get
			{
				return this.windowCanvas;
			}
		}

		// Token: 0x17000002 RID: 2
		// (get) Token: 0x06000005 RID: 5 RVA: 0x000022D8 File Offset: 0x000004D8
		public HWindow HalconWindow
		{
			get
			{
				if (this.window != null)
				{
					return this.window;
				}
				return new HWindow();
			}
		}

		// Token: 0x17000003 RID: 3
		// (get) Token: 0x06000006 RID: 6 RVA: 0x000022EE File Offset: 0x000004EE
		public IntPtr HalconID
		{
			get
			{
				if (this.window != null)
				{
					return this.window.Handle;
				}
				return HHandleBase.UNDEF;
			}
		}

		// Token: 0x06000007 RID: 7 RVA: 0x0000230C File Offset: 0x0000050C
		private void windowCanvas_SizeChanged(object sender, SizeChangedEventArgs e)
		{
			if (this.windowWPF != null)
			{
				try
				{
					this.windowWPF.SetWindowExtents((int)this.windowCanvas.ActualWidth, (int)this.windowCanvas.ActualHeight);
					if (HSystem.GetSystem(new HTuple("flush_graphic")).S == "true")
					{
						this.windowWPF.UpdateLayout();
					}
				}
				catch (HOperatorException)
				{
				}
			}
		}

		// Token: 0x06000008 RID: 8 RVA: 0x00002384 File Offset: 0x00000584
		private void windowCanvas_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
		{
			if ((bool)e.NewValue)
			{
				this.ApplyScalingFactor(this);
				this.windowCanvas.IsVisibleChanged -= this.windowCanvas_IsVisibleChanged;
			}
		}

		// Token: 0x06000009 RID: 9 RVA: 0x000023B4 File Offset: 0x000005B4
		private void UpdatePart()
		{
			if (this.windowWPF == null || this.windowWPF.HalconWindow == null)
			{
				return;
			}
			this.windowWPF.HalconWindow.SetPart((int)this.imagePart.Top, (int)this.imagePart.Left, (int)(this.imagePart.Top + this.imagePart.Height - 1.0), (int)(this.imagePart.Left + this.imagePart.Width - 1.0));
		}

		/// <summary>
		///  This rectangle specifies the image part to be displayed.
		///  The method SetFullImagePart() will adapt this property to
		///  show the full image.
		/// </summary>
		// Token: 0x17000004 RID: 4
		// (get) Token: 0x0600000A RID: 10 RVA: 0x00002444 File Offset: 0x00000644
		// (set) Token: 0x0600000B RID: 11 RVA: 0x0000249F File Offset: 0x0000069F
		public Rect ImagePart
		{
			get
			{
				if (this.windowWPF != null && this.windowWPF.HalconWindow != null)
				{
					int num;
					int num2;
					int num3;
					int num4;
					this.windowWPF.HalconWindow.GetPart(out num, out num2, out num3, out num4);
					this.imagePart = new Rect((double)num2, (double)num, (double)(num4 - num2 + 1), (double)(num3 - num + 1));
				}
				return this.imagePart;
			}
			set
			{
				this.imagePart = new Rect((double)((int)value.Left), (double)((int)value.Top), (double)((int)value.Width), (double)((int)value.Height));
				this.UpdatePart();
			}
		}

		/// <summary>
		///   Adapt ImagePart to show the full image.
		/// </summary>
		/// <param name="reference">The image used as reference</param>
		// Token: 0x0600000C RID: 12 RVA: 0x000024D8 File Offset: 0x000006D8
		public void SetFullImagePart(HImage reference)
		{
			string text;
			int num;
			int num2;
			reference.GetImagePointer1(out text, out num, out num2);
			this.imagePart = new Rect(0.0, 0.0, (double)num, (double)num2);
			this.UpdatePart();
		}

		/// <summary>
		///   Sets the focus to this component, which is necessary
		///   for obtaining mouse wheel events via HMouseWheel.
		/// </summary>
		/// <remarks>
		///   If Focusable is true the focus will be set automatically
		///   when clicking into the window. Also, Focusable will be set
		///   to true automatically when calling this method.
		/// </remarks>
		// Token: 0x0600000D RID: 13 RVA: 0x00002519 File Offset: 0x00000719
		public new bool Focus()
		{
			base.Focusable = true;
			this.windowWPF.SetNativeFocus();
			return true;
		}

		// Token: 0x0600000E RID: 14 RVA: 0x0000252E File Offset: 0x0000072E
		void IDisposable.Dispose()
		{
			this.Dispose();
		}

		/// <summary>Releases the resources used by the native HALCON window</summary>
		// Token: 0x0600000F RID: 15 RVA: 0x00002536 File Offset: 0x00000736
		public virtual void Dispose()
		{
			if (this.windowWPF != null)
			{
				this.windowWPF.Dispose();
				this.windowWPF = null;
			}
		}

		/// <summary>
		///   Occurs when the HALCON window has been initialized.
		///   Note that this occurs *after* the event "Loaded".
		/// </summary>
		// Token: 0x14000001 RID: 1
		// (add) Token: 0x06000010 RID: 16 RVA: 0x00002554 File Offset: 0x00000754
		// (remove) Token: 0x06000011 RID: 17 RVA: 0x0000258C File Offset: 0x0000078C
		public event HInitWindowEventHandlerWPF HInitWindow;

		// Token: 0x06000012 RID: 18 RVA: 0x000025C1 File Offset: 0x000007C1
		protected virtual void OnHInitWindow()
		{
			if (this.HInitWindow != null)
			{
				this.HInitWindow(this, new EventArgs());
			}
		}

		/// <summary>
		///   Occurs when the mouse is moved over a HALCON window. Note that
		///   delta is meaningless here.
		/// </summary>
		// Token: 0x14000002 RID: 2
		// (add) Token: 0x06000013 RID: 19 RVA: 0x000025DC File Offset: 0x000007DC
		// (remove) Token: 0x06000014 RID: 20 RVA: 0x00002614 File Offset: 0x00000814
		public event HMouseEventHandlerWPF HMouseMove;

		/// <summary>
		///   Occurs when a button is pressed over a HALCON window. Note that
		///   delta is meaningless here.
		/// </summary>
		// Token: 0x14000003 RID: 3
		// (add) Token: 0x06000015 RID: 21 RVA: 0x0000264C File Offset: 0x0000084C
		// (remove) Token: 0x06000016 RID: 22 RVA: 0x00002684 File Offset: 0x00000884
		public event HMouseEventHandlerWPF HMouseDown;

		/// <summary>
		///   Occurs when a button is released over a HALCON window. Note that
		///   delta is meaningless here.
		/// </summary>
		// Token: 0x14000004 RID: 4
		// (add) Token: 0x06000017 RID: 23 RVA: 0x000026BC File Offset: 0x000008BC
		// (remove) Token: 0x06000018 RID: 24 RVA: 0x000026F4 File Offset: 0x000008F4
		public event HMouseEventHandlerWPF HMouseUp;

		/// <summary>
		///   Occurs when the wheel is used over a HALCON window while it has
		///   focus. Note that button is meaningless here.
		/// </summary>
		// Token: 0x14000005 RID: 5
		// (add) Token: 0x06000019 RID: 25 RVA: 0x0000272C File Offset: 0x0000092C
		// (remove) Token: 0x0600001A RID: 26 RVA: 0x00002764 File Offset: 0x00000964
		public event HMouseEventHandlerWPF HMouseWheel;

		// Token: 0x0600001B RID: 27 RVA: 0x00002799 File Offset: 0x00000999
		protected virtual void OnHMouseMove(HMouseEventArgsWPF e)
		{
			if (this.HMouseMove != null)
			{
				this.HMouseMove(this, e);
			}
		}

		// Token: 0x0600001C RID: 28 RVA: 0x000027B0 File Offset: 0x000009B0
		protected virtual void OnHMouseDown(HMouseEventArgsWPF e)
		{
			if (this.HMouseDown != null)
			{
				this.HMouseDown(this, e);
			}
		}

		// Token: 0x0600001D RID: 29 RVA: 0x000027C7 File Offset: 0x000009C7
		protected virtual void OnHMouseUp(HMouseEventArgsWPF e)
		{
			if (this.HMouseUp != null)
			{
				this.HMouseUp(this, e);
			}
		}

		// Token: 0x0600001E RID: 30 RVA: 0x000027DE File Offset: 0x000009DE
		protected virtual void OnHMouseWheel(HMouseEventArgsWPF e)
		{
			if (this.HMouseWheel != null)
			{
				this.HMouseWheel(this, e);
			}
		}

		// Token: 0x0600001F RID: 31 RVA: 0x000027F8 File Offset: 0x000009F8
		private HMouseEventArgsWPF ToHMouse(int x, int y, MouseButton? button, int delta)
		{
			double row;
			double column;
			if (this.window == null)
			{
				row = ((this.windowWPF == null) ? ((double)y) : (this.imagePart.Top + (double)y * this.imagePart.Height / this.windowWPF.Height));
				column = ((this.windowWPF == null) ? ((double)x) : (this.imagePart.Left + (double)x * this.imagePart.Width / this.windowWPF.Width));
			}
			else
			{
				this.window.ConvertCoordinatesWindowToImage((double)y, (double)x, out row, out column);
			}
			return new HMouseEventArgsWPF((double)x, (double)y, row, column, delta, button);
		}

		// Token: 0x06000020 RID: 32 RVA: 0x00002896 File Offset: 0x00000A96
		private void windowWPF_InitEvent()
		{
			this.window = this.windowWPF.HalconWindow;
			this.UpdatePart();
			base.Focusable = true;
			this.OnHInitWindow();
		}

		// Token: 0x06000021 RID: 33 RVA: 0x000028BC File Offset: 0x00000ABC
		private void windowWPF_ButtonEvent(int x, int y, MouseButton button, MouseButtonState state)
		{
			if (state == MouseButtonState.Released)
			{
				this.OnHMouseUp(this.ToHMouse(x, y, new MouseButton?(button), 0));
				return;
			}
			this.OnHMouseDown(this.ToHMouse(x, y, new MouseButton?(button), 0));
			if (base.Focusable)
			{
				this.windowWPF.SetNativeFocus();
			}
		}

		// Token: 0x06000022 RID: 34 RVA: 0x0000290C File Offset: 0x00000B0C
		private void windowWPF_MouseEvent(int x, int y, MouseButton? button, int delta)
		{
			if (delta == 0)
			{
				this.OnHMouseMove(this.ToHMouse(x, y, button, 0));
				return;
			}
			this.OnHMouseWheel(this.ToHMouse(x, y, null, delta));
		}

		// Token: 0x04000001 RID: 1
		private Canvas windowCanvas;

		// Token: 0x04000002 RID: 2
		private HWindowWPF windowWPF;

		// Token: 0x04000003 RID: 3
		private HWindow window;

		// Token: 0x04000004 RID: 4
		private Rect imagePart = new Rect(0.0, 0.0, 640.0, 480.0);
	}
}
